﻿using Autofac;
using AutoMapper;
using Foundation.AutoMapper;
using Foundation.Caching;
using Foundation.DistributeLock.RedLock;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Dyao.Book.Web.Extensions
{
    public static class ApplicationBuilderExtensions
    {
        public static IApplicationBuilder UseObjectMapping(this IApplicationBuilder builder)
        {

            using (var scope = builder.ApplicationServices.CreateScope())
            {
                var options = scope.ServiceProvider.GetRequiredService<IOptionsMonitor<AutoMapperOptions>>().CurrentValue;

                void ConfigureAll(IAutoMapperConfigurationContext ctx)
                {
                    foreach (var configurator in options.Configurators)
                    {
                        configurator(ctx);
                    }
                }

                void ValidateAll(AutoMapper.IConfigurationProvider config)
                {
                    foreach (var profileType in options.ValidatingProfiles)
                    {
                        config.AssertConfigurationIsValid();
                    }
                }

                var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression =>
                {
                    ConfigureAll(new AutoMapperConfigurationContext(mapperConfigurationExpression, scope.ServiceProvider));
                });

                ValidateAll(mapperConfiguration);

                scope.ServiceProvider.GetRequiredService<MapperAccessor>().Mapper = mapperConfiguration.CreateMapper();
            }
            return builder;
        }

        /// <summary>
        /// 分布式锁
        /// </summary>
        /// <param name="rootServiceProvider"></param>
        public static IApplicationBuilder UseRedLock(this IApplicationBuilder builder)
        {

            using (var scope = builder.ApplicationServices.CreateScope())
            {
                var configration = scope.ServiceProvider.GetService<IConfiguration>();
                var multiplexers = configration.GetSection(nameof(RedLockOptions)).Get<RedLockOptions>().Multiplexers;
                var loggerFactory = scope.ServiceProvider.GetService<ILoggerFactory>();
                RedLockOptionsBuilder.Build(builder =>
                {
                    return builder.Multiplexers(multiplexers)
                    .LoggerFactory(loggerFactory);
                });
            }

            return builder;
        }

        /// <summary>
        /// 添加缓存方法
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="scope"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseCachingCollector(this IApplicationBuilder builder, ILifetimeScope scope)
        {
            var methodCache = scope.Resolve<MethodMatcherCache>();
            methodCache.GetCandidatesMethods();
            return builder;
        }
    }
}
